package edu.hawaii.myisern.commandline;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.meterware.httpunit.WebConversation;
import edu.hawaii.myisern.collaborations.jaxb.CollaboratingOrganizations;
import edu.hawaii.myisern.collaborations.jaxb.Collaboration;
import edu.hawaii.myisern.collaborations.jaxb.CollaborationTypes;
import edu.hawaii.myisern.collaborations.jaxb.OutcomeTypes;
import edu.hawaii.myisern.collaborations.jaxb.Years;
import edu.hawaii.myisern.organizations.jaxb.AffiliatedResearchers;
import edu.hawaii.myisern.organizations.jaxb.Organization;
import edu.hawaii.myisern.organizations.jaxb.ResearchKeywords;
import edu.hawaii.myisern.researchers.jaxb.Researcher;

/**
 * Allows the user to input new collaborations, organizations, and researchers.
 * 
 * @author Phuoc Le
 * @author Ka Yee Leung
 * @author Jared Sunouchi
 */
public class MyIsernInput {

  private static InputStreamReader streamReader = new InputStreamReader(System.in);
  private static BufferedReader reader = new BufferedReader(streamReader);
  private static final String save = "save";
  private static final String cancel = "cancel";
  private static final String http = "http://";
  private static final String www = "www.";
  private static final String homepageInvalid = "Homepage is not valid. " +
  		"Please enter another one: ";
  private static final String command = "command: ";
  private static final String delete = "delete";
  private static final String invalidCommand = "Invalid command. Please enter either 'a', 'e', " +
  		"or press 'enter'";
  private static final String saveOrCancel = "Correct command not entered. Type 'save' to save " +
  		"or 'cancel' to cancel: ";
  
  /**
   * Tests the Input ability by reading input from a file and loading XML data from a source.
   * 
   * @param file The file containing the input data.
   * @param loader The object containing the XML data.
   * @throws Exception If problems occur.
   */
  public static void setBufferedReaderAndRunInput(FileReader file, MyIsernXmlLoader loader)
      throws Exception {
    reader = new BufferedReader(file);
    runInput(loader);
  }
  
  /**
   * Runs the Input ability using the default XML files.
   * 
   * @throws Exception If problems occur.
   */
  public static void run() throws Exception {
    MyIsernXmlLoader loader = new MyIsernXmlLoader();
    loader.sanityCheck();
    runInput(loader);
  }
  
  /**
   * Runs the command line interface for the MyISERN system.
   * 
   * @param loader The object containing the XML data.
   * @throws Exception If problems occur during input.
   */
  public static void runInput(MyIsernXmlLoader loader) throws Exception {
    System.out.println();
    System.out.println(loader.getXmlFilesName());
    String command = "";
    
    List<String> commands = new ArrayList<String>();
    commands.add("add researcher");
    commands.add("add r");
    commands.add("add organization");
    commands.add("add o");
    commands.add("add collaboration");
    commands.add("add c");
    commands.add("quit");
    commands.add("q");

    while (!("quit".equals(command)) && !("q".equals(command))) {
      System.out.println();
      System.out.println("Enter one of the following commands (abbreviated version):");
      System.out.println("   add researcher (add r)");
      System.out.println("   add organization (add o)");
      System.out.println("   add collaboration (add c)");
      System.out.println("   quit (q)");
      System.out.println();
      System.out.print("Enter command: ");

      command = reader.readLine();
      command = command.trim();

      while (!(commands.contains(command))) {
        System.out.println();
        System.out.print("Command not recognized. Please enter a valid command: ");
        command = reader.readLine();
        command = command.trim();
      }

      System.out.println();

      if (("add collaboration".equals(command)) || ("add c".equals(command))) {
        addCollaboration(loader);
      }
      if (("add organization".equals(command)) || ("add o".equals(command))) {
        addOrganization(loader);
      }
      if (("add researcher".equals(command))  || ("add r".equals(command))) {
        addResearcher(loader);
      }
    }
  }

  /**
   * Adds a collaboration to the system or allows the user to edit an existing one.
   * 
   * @param loader The MyIsernXmlLoader object that contains and checks the data.
   * @throws Exception If problems occur.
   */
  public static void addCollaboration(MyIsernXmlLoader loader) throws Exception {
    Map<String, String> uniqueIds = loader.getUniqueIds();

    System.out.println("Adding a Collaboration");
    String name;
    String organizationsString;
    CollaboratingOrganizations organizations = new CollaboratingOrganizations();
    String typesString;
    CollaborationTypes types = new CollaborationTypes();
    String yearsString;
    Years yearsList = new Years();
    String outcomesString;
    OutcomeTypes outcomes = new OutcomeTypes();
    String description;
    Collaboration newCollaboration = new Collaboration();

    System.out.print("Enter collaboration name: ");
    name = reader.readLine();
    while (name.isEmpty()) {
      System.out.println("Please enter collaboration name again: ");
      name = reader.readLine();
    }
    name = name.replace(' ', '_');
    if (uniqueIds.containsKey(name)) {
      editCollaboration(name, loader);
    }
    else {
      System.out.println();
      System.out.println("If any of the following information does not apply to you,");
      System.out.println("please press 'enter' to go to the next one.");
      System.out.println();
      
      System.out.print("Enter collaborating organizations (separate by commas): ");
      organizationsString = reader.readLine();
      organizations = modifyCollaboratingOrganizations(organizationsString, organizations);

      System.out.print("Enter collaboration types (separate by commas): ");
      typesString = reader.readLine();
      types = modifyCollaborationTypes(typesString, types);

      System.out.print("Enter years (separate by commas): ");
      yearsString = reader.readLine();
      yearsList = modifyYears(yearsString, yearsList);

      System.out.print("Enter outcome types (separate by commas): ");
      outcomesString = reader.readLine();
      outcomes = modifyOutcomeTypes(outcomesString, outcomes);

      System.out.print("Enter description: ");
      description = reader.readLine();

      newCollaboration.setName(name.replace('_', ' '));
      newCollaboration.setCollaboratingOrganizations(organizations);
      newCollaboration.setCollaborationTypes(types);
      newCollaboration.setYears(yearsList);
      newCollaboration.setOutcomeTypes(outcomes);
      newCollaboration.setDescription(description);

      System.out.println();
      System.out.print("Type 'save' to save this collaboration or 'cancel' to cancel: ");
      String command = reader.readLine();
      while ((!(save.equals(command))) && (!(cancel.equals(command)))) {
        System.out.print(saveOrCancel);
        command = reader.readLine();
      }
      if (save.equals(command)) {
        loader.getCollaborations().getCollaboration().add(newCollaboration);
        String newCollaborationsXml = loader.getCollaborationsXml();
        File organizationsFile = new File(loader.getCollaborationsFilePath());
        FileOutputStream fos = new FileOutputStream(organizationsFile);
        fos.write(newCollaborationsXml.getBytes());
        System.out.println();
        System.out.println("Collaboration: " + newCollaboration.getName()
            + " has been successfully added.");
      }
      else {
        System.out.println("Collaboration was discarded.");
      }
    }
  }

  /**
   * Adds an organization to the system or allows the user to edit an existing one.
   * 
   * @param loader The MyIsernXmlLoader object that contains and checks the data.
   * @throws Exception If problems occur.
   */
  public static void addOrganization(MyIsernXmlLoader loader) throws Exception {
    Map<String, String> uniqueIds = loader.getUniqueIds();

    System.out.println("Adding an Organization");
    String name;
    String type;
    String contact;
    AffiliatedResearchers researchers = new AffiliatedResearchers();
    String researcherString;
    String country;
    ResearchKeywords keywords = new ResearchKeywords();
    String keywordString;
    String researchDescription;
    String homepage;
    Organization org = new Organization();

    System.out.print("Enter organization name: ");
    name = reader.readLine();
    while (name.isEmpty()) {
      System.out.println("Please enter organization name again: ");
      name = reader.readLine();
    }
    name = name.replace(' ', '_');
    if (uniqueIds.containsKey(name)) {
      editOrganization(name, loader);
    }
    else {
      System.out.println();
      System.out.println("If any of the following information does not apply to you,");
      System.out.println("please press 'enter' to go to the next one.");
      System.out.println();
      
      System.out.print("Enter organization type: ");
      type = reader.readLine();
      System.out.print("Enter contact name: ");
      contact = reader.readLine();

      System.out.print("Enter affilated researchers (separate by commas): ");
      researcherString = reader.readLine();
      researchers = modifyAffiliatedResearchers(researcherString, researchers);

      System.out.print("Enter country: ");
      country = reader.readLine();

      System.out.print("Enter research keywords (separate by commas): ");
      keywordString = reader.readLine();
      keywords = modifyResearchKeywords(keywordString, keywords);

      System.out.print("Enter research description: ");
      researchDescription = reader.readLine();
      System.out.print("Enter homepage: ");
      homepage = reader.readLine();

      while ((!(homepage.length() > 5)) && (!(homepage.length() == 0))) {
        System.out.println("Invalid URL. Please enter another one: ");
        homepage = reader.readLine();
      }

      //Checks to make sure the link is valid or no link was entered.  
      while (!("".equals(homepage)) && (!(checkLink(homepage)))) {
        if (!(http.equalsIgnoreCase(homepage.substring(0, 6)))) {
          if (www.equalsIgnoreCase(homepage.substring(0, 3))) {
            homepage = http + homepage;
          }
          else {
            homepage = http + www + homepage;
          }
        }
        if (!(checkLink(homepage))) {
          System.out.println(homepageInvalid);
          homepage = reader.readLine();
        }
      }
      if ("".equals(homepage)) {
        homepage = "";
        System.out.println("No homepage was entered.");
      }

      org.setName(name.replace('_', ' '));
      org.setType(type);
      org.setContact(contact);
      org.setAffiliatedResearchers(researchers);
      org.setCountry(country);
      org.setResearchKeywords(keywords);
      org.setResearchDescription(researchDescription);
      org.setHomePage(homepage);

      System.out.println();
      System.out.print("Type 'save' to save this organization or 'cancel' to cancel: ");
      String command = reader.readLine();
      while ((!(save.equals(command))) && (!(cancel.equals(command)))) {
        System.out.print(saveOrCancel);
        command = reader.readLine();
      }
      if (save.equals(command)) {
        loader.getOrganizations().getOrganization().add(org);
        String newOrganizationsXml = loader.getOrganizationsXml();
        File organizationsFile = new File(loader.getOrganizationsFilePath());
        FileOutputStream fos = new FileOutputStream(organizationsFile);
        fos.write(newOrganizationsXml.getBytes());
        System.out.println();
        System.out.println("Organization: " + org.getName() + " has been successfully added.");
      }
      else {
        System.out.println("Organization was discarded.");
      }
    }
  }

  /**
   * Adds a collaboration to the system or allows the user to edit an existing one.
   * 
   * @param loader The MyIsernXmlLoader object that contains and checks the data.
   * @throws Exception If problems occur.
   */
  public static void addResearcher(MyIsernXmlLoader loader) throws Exception {
    Map<String, String> uniqueIds = loader.getUniqueIds();

    System.out.println("Adding an Researcher");
    String name;
    String organization;
    String email;
    String pictureLink;
    String bioStatement;
    Researcher researcher = new Researcher();

    System.out.print("Enter researcher name: ");
    name = reader.readLine();
    while (name.isEmpty()) {
      System.out.println("Please enter researcher name again: ");
      name = reader.readLine();
    }
    name = name.replace(' ', '_');
    //If the researcher already exists in the database, edit its original data instead.
    if (uniqueIds.containsKey(name)) {
      System.out.println("Edit researcher");
      editResearcher(name, loader);
    }
    else {
      System.out.println();
      System.out.println("If any of the following information does not apply to you,");
      System.out.println("please press 'enter' to go to the next one.");
      System.out.println();
      
      System.out.print("Enter organization: ");
      organization = reader.readLine();

      System.out.print("Enter email: ");
      email = reader.readLine();

      //Ensure the email addressed entered is valid
      while (((!(email.contains("@"))) || (!(email.contains(".")))) && (!("".equals(email)))) {
        System.out.println("Invalid email. Please enter again:");
        email = reader.readLine();
      }

      System.out.print("Enter Bio-statement: ");
      bioStatement = reader.readLine();

      System.out.print("Enter picture link: ");
      pictureLink = reader.readLine();

      while ((!(pictureLink.length() > 5)) && (!(pictureLink.length() == 0))) {
        System.out.println("Invalid URL. Please enter another one: ");
        pictureLink = reader.readLine();
      }

      while (!("".equals(pictureLink)) && (!(checkLink(pictureLink)))) {
        if (!(http.equalsIgnoreCase(pictureLink.substring(0, 6)))) {
          if (www.equalsIgnoreCase(pictureLink.substring(0, 3))) {
            pictureLink = http + pictureLink;
          }
          else {
            pictureLink = http + www + pictureLink;
          }
        }
        if (!(checkLink(pictureLink))) {
          System.out.println(homepageInvalid);
          pictureLink = reader.readLine();
        }
      }
      if ("".equals(pictureLink)) {
        pictureLink = "";
        System.out.println("No homepage was entered.");
      }

      researcher.setName(name.replace('_', ' '));
      researcher.setBioStatement(bioStatement);
      researcher.setOrganization(organization);
      researcher.setEmail(email);
      researcher.setPictureLink(pictureLink);

      System.out.println();
      System.out.print("Type 'save' to save this researcher or 'cancel' to cancel: ");
      String command = reader.readLine();
      while ((!(save.equals(command))) && (!(cancel.equals(command)))) {
        System.out.print(saveOrCancel);
        command = reader.readLine();
      }
      if (save.equals(command)) {
        loader.getResearchers().getResearcher().add(researcher);
        String newResearchersXml = loader.getResearchersXml();
        File researchersFile = new File(loader.getRsearchersFilePath());
        FileOutputStream fos = new FileOutputStream(researchersFile);
        fos.write(newResearchersXml.getBytes());
        System.out.println();
        System.out.println("Researcher: " + researcher.getName() + " has been successfully added.");
      }
      else {
        System.out.println("Researcher was discarded.");
      }
    }
  }

  /**
   * Edit the information of the given researcher in the MyIsern Social Network.
   * 
   * @param id Unique ID of the researcher.
   * @param myIsernXml The MyIsernXmlLoader object that contains and checks the data.
   * @throws Exception If problems occur.
   */
  public static void editResearcher(String id, MyIsernXmlLoader myIsernXml) throws Exception {
    String organization;
    String email;
    String pictureLink;
    String bioStatement;
    Researcher researcher = new Researcher();

    List<Researcher> researchersList = myIsernXml.getResearchers().getResearcher();
    int count = 0;
    for (Researcher researchers : researchersList) {
      if (researchers.getName().equals(id.replace('_', ' '))) {
        System.out.println(researchers.getName());
        researcher = researchers;
        count = researchersList.indexOf(researcher);
      }
    }

    System.out.println();
    System.out.println("Editing researcher: " + id.replace('_', ' '));
    System.out.println("To keep values the same just press 'enter'.");

    System.out.println();
    System.out.println("Current organization is: " + researcher.getOrganization());
    System.out.print("Edit organization: ");
    organization = reader.readLine();
    if ("".equals(organization)) {
      organization = researcher.getOrganization();
      System.out.println("Organization has remained the same.");
    }

    System.out.println();
    System.out.println("Current email is: " + researcher.getEmail());
    System.out.print("Edit email: ");
    email = reader.readLine();
    while (((!(email.contains("@"))) || (!(email.contains(".")))) && (!("".equals(email)))) {
      System.out.println("Invalid email. Please enter again:");
      email = reader.readLine();
    }
    if ("".equals(email)) {
      email = researcher.getEmail();
      System.out.println("Email has remained the same.");
    }

    System.out.println();
    System.out.println("Current bioStatement is: " + researcher.getBioStatement());
    System.out.print("Edit Bio-Statement: ");
    bioStatement = reader.readLine();
    if ("".equals(bioStatement)) {
      bioStatement = researcher.getBioStatement();
      System.out.println("Bio-Statement has remained the same.");
    }

    System.out.println();
    System.out.println("Current picture link is: " + researcher.getPictureLink());
    System.out.print("Enter homepage (to delete current homepage, type -delete: )");
    pictureLink = reader.readLine();

    while ((!(pictureLink.length() > 5)) && (!(pictureLink.length() == 0))) {
      System.out.println("Invalid URL or command. Please enter another one: ");
      pictureLink = reader.readLine();
    }

    while (!(delete.equals(pictureLink)) && !("".equals(pictureLink))
        && (!(checkLink(pictureLink)))) {
      if (!(http.equalsIgnoreCase(pictureLink.substring(0, 6)))) {
        if (www.equalsIgnoreCase(pictureLink.substring(0, 3))) {
          pictureLink = http + pictureLink;
        }
        else {
          pictureLink = http + www + pictureLink;
        }
      }
      if (!(checkLink(pictureLink))) {
        System.out.println(homepageInvalid);
        pictureLink = reader.readLine();
      }
    }
    if ("".equals(pictureLink)) {
      pictureLink = researcher.getPictureLink();
      System.out.println("Homepage has remained the same.");
    }
    else if (delete.equals(pictureLink)) {
      pictureLink = "http://www.google.com";
      System.out.println("Original homepage has been deleted.");
    }

    researcher.setBioStatement(bioStatement);
    researcher.setEmail(email);
    researcher.setOrganization(organization);
    researcher.setPictureLink(pictureLink);

    System.out.println();
    System.out.print("Type 'save' to save this organization or 'cancel' to cancel: ");
    String choice = reader.readLine();
    while ((!(save.equals(choice))) && (!(cancel.equals(choice)))) {
      System.out.print(saveOrCancel);
      choice = reader.readLine();
    }
    if (save.equals(choice)) {
      myIsernXml.getResearchers().getResearcher().set(count, researcher);
      String newResearchersXml = myIsernXml.getResearchersXml();
      File researchersFile = new File(myIsernXml.getRsearchersFilePath());
      FileOutputStream fos = new FileOutputStream(researchersFile);
      fos.write(newResearchersXml.getBytes());
      System.out.println();
      System.out.println("Researcher: " + researcher.getName() + " has been successfully edited.");
    }
    else {
      System.out.println("Researcher: " + researcher.getName() + " remains the same.");
    }
  }

  /**
   * Edits a collaboration that already exists in the network.
   * 
   * @param id Unique ID of the collaboration.
   * @param myIsernXml The MyIsernXmlLoader object that contains and checks the data.
   * @throws Exception If problems occur.
   */
  public static void editCollaboration(String id, MyIsernXmlLoader myIsernXml) throws Exception {
    String organizationsString;
    CollaboratingOrganizations organizations = new CollaboratingOrganizations();
    String typesString;
    CollaborationTypes types = new CollaborationTypes();
    String yearsString;
    Years yearsList = new Years();
    String outcomesString;
    OutcomeTypes outcomes = new OutcomeTypes();
    String description;

    Collaboration newCollaboration = new Collaboration();

    List<Collaboration> collaborationsList = myIsernXml.getCollaborations().getCollaboration();
    int count = 0;
    for (Collaboration collaboration : collaborationsList) {
      if (collaboration.getName().equals(id.replace('_', ' '))) {
        newCollaboration = collaboration;
        count = collaborationsList.indexOf(newCollaboration);
      }
    }

    System.out.println();
    System.out.println("Editing collaboration: " + id.replace('_', ' '));
    System.out.println("To keep values the same just press 'enter'.");

    System.out.println();
    MyIsernTableCreator creator = new MyIsernTableCreator(myIsernXml);
    String organizationsList = creator.createListString(newCollaboration
        .getCollaboratingOrganizations().getCollaboratingOrganization());
    System.out.println("Current collaborating organizations are: " + organizationsList);
    System.out.println("To edit collaborating organizations, enter 'e'. ");
    System.out.println("To add new collaborating organizations, enter 'a'");
    System.out.print(command);
    String choice = reader.readLine();

    while (!("e".equalsIgnoreCase(choice)) && !("a".equalsIgnoreCase(choice))
        && !("".equalsIgnoreCase(choice))) {
      System.out.println(invalidCommand);
      choice = reader.readLine();
    }

    if ("e".equalsIgnoreCase(choice)) {
      System.out.print("Edit collaborating organizations (separate by commas): ");
      organizationsString = reader.readLine();
      organizations = modifyCollaboratingOrganizations(organizationsString, organizations);
    }
    else if ("a".equalsIgnoreCase(choice)) {
      System.out.print("Add collaborating organizations (separate by commas): ");
      organizationsString = reader.readLine();
      organizations = newCollaboration.getCollaboratingOrganizations();
      organizations = modifyCollaboratingOrganizations(organizationsString, organizations);
    }
    else if ("".equals(choice)) {
      System.out.println("Collaborating organizations have remained the same.");
      organizations = newCollaboration.getCollaboratingOrganizations();
    }

    System.out.println();
    String typesList = creator.createListString(newCollaboration.getCollaborationTypes()
        .getCollaborationType());
    System.out.println("Current collaboration types are: " + typesList);
    System.out.println("To edit collaboration types , enter 'e'.");
    System.out.println("To add new collaboration types , enter 'a'.");
    System.out.print(command);
    choice = reader.readLine();

    while (!("e".equalsIgnoreCase(choice)) && !("a".equalsIgnoreCase(choice))
        && !("".equalsIgnoreCase(choice))) {
      System.out.println(invalidCommand);
      choice = reader.readLine();
    }

    if ("e".equalsIgnoreCase(choice)) {
      System.out.print("Edit collaboration types (separate by commas): ");
      typesString = reader.readLine();
      types.getCollaborationType().clear();
      types = modifyCollaborationTypes(typesString, types);
    }
    else if ("a".equalsIgnoreCase(choice)) {
      System.out.print("Add collaboration types (separate by commas): ");
      typesString = reader.readLine();
      types = newCollaboration.getCollaborationTypes();
      types = modifyCollaborationTypes(typesString, types);
    }
    else if ("".equals(choice)) {
      System.out.println("Collaboration types have remained the same.");
      types = newCollaboration.getCollaborationTypes();
    }

    System.out.println();
    try {
    List<BigInteger> listOfYears = newCollaboration.getYears().getYear();
    int listSize = listOfYears.size();
    int listCount = 1;
    StringBuffer yearNames = new StringBuffer();
    for (BigInteger year : listOfYears) {
      yearNames.append(year.toString());
      if (listCount < listSize) {
        String separator = ", ";
        yearNames.append(separator);
      }
      listCount++;
    }
    String years = yearNames.toString();
    System.out.println("Current years are: " + years);
    }
    catch (Exception e) {
      System.out.println("There is no year entered for this collaboration");
    }
    System.out.println("To edit years, enter 'e'.");
    System.out.println("To add new years, enter 'a'.");
    System.out.print(command);
    choice = reader.readLine();

    while (!("e".equalsIgnoreCase(choice)) && !("a".equalsIgnoreCase(choice))
        && !("".equalsIgnoreCase(choice))) {
      System.out.println(invalidCommand);
      choice = reader.readLine();
    }

    if ("e".equalsIgnoreCase(choice)) {
      System.out.print("Edit years(separate by commas): ");
      yearsString = reader.readLine();
      yearsList = modifyYears(yearsString, yearsList);
    }
    else if ("a".equalsIgnoreCase(choice)) {
      System.out.print("Add years(separate by commas): ");
      yearsString = reader.readLine();
      yearsList = newCollaboration.getYears();
      yearsList = modifyYears(yearsString, yearsList);
    }
    else if ("".equals(choice)) {
      System.out.println("Years have remained the same.");
      yearsList = newCollaboration.getYears();
    }

    System.out.println();
    String outcomesList = creator.createListString(newCollaboration.getOutcomeTypes()
        .getOutcomeType());
    System.out.println("Current outcome types are: " + outcomesList);
    System.out.println("To edit outcome types, enter 'e'.");
    System.out.println("To add new outcome types, enter 'a'.");
    System.out.print(command);
    choice = reader.readLine();

    while (!("e".equalsIgnoreCase(choice)) && !("a".equalsIgnoreCase(choice))
        && !("".equalsIgnoreCase(choice))) {
      System.out.println(invalidCommand);
      choice = reader.readLine();
    }

    if ("e".equalsIgnoreCase(choice)) {
      System.out.print("Edit outcome types (separate by commas): ");
      outcomesString = reader.readLine();
      outcomes = modifyOutcomeTypes(outcomesString, outcomes);
    }
    else if ("a".equalsIgnoreCase(choice)) {
      System.out.print("Add outcome types (separate by commas): ");
      outcomesString = reader.readLine();
      outcomes = newCollaboration.getOutcomeTypes();
      outcomes = modifyOutcomeTypes(outcomesString, outcomes);
    }
    else if ("".equals(choice)) {
      System.out.println("Outcome types have remained the same.");
    }

    System.out.println();
    System.out.println("Current descripton is: " + newCollaboration.getDescription());
    System.out.print("Edit description: ");
    description = reader.readLine();
    if ("".equals(description)) {
      description = newCollaboration.getDescription();
      System.out.println("Description has remained the same.");
    }

    newCollaboration.setCollaboratingOrganizations(organizations);
    newCollaboration.setCollaborationTypes(types);
    newCollaboration.setYears(yearsList);
    newCollaboration.setOutcomeTypes(outcomes);
    newCollaboration.setDescription(description);

    System.out.println();
    System.out.print("Type 'save' to save this collaboration or 'cancel' to cancel: ");
    String command = reader.readLine();
    while ((!(save.equals(command))) && (!(cancel.equals(command)))) {
      System.out.print(saveOrCancel);
      command = reader.readLine();
    }
    if (save.equals(command)) {
      myIsernXml.getCollaborations().getCollaboration().set(count, newCollaboration);
      String newCollaborationsXml = myIsernXml.getCollaborationsXml();
      File organizationsFile = new File(myIsernXml.getCollaborationsFilePath());
      FileOutputStream fos = new FileOutputStream(organizationsFile);
      fos.write(newCollaborationsXml.getBytes());
      System.out.println();
      System.out.println("Collaboration: " + newCollaboration.getName()
          + " has been successfully edited.");
    }
    else {
      System.out.println("Collaboration: " + newCollaboration.getName() + " remains the same.");
    }
  }

  /**
   * Edits an organization that already exists in the network.
   * 
   * @param id Unique ID of the organization.
   * @param myIsernXml The MyIsernXmlLoader object that contains and checks the data.
   * @throws Exception If problems occur.
   */
  public static void editOrganization(String id, MyIsernXmlLoader myIsernXml) throws Exception {
    String type;
    String contact;
    AffiliatedResearchers researchers = new AffiliatedResearchers();
    String researcherString;
    String country;
    ResearchKeywords keywords = new ResearchKeywords();
    String keywordString;
    String researchDescription;
    String homepage;

    Organization org = new Organization();

    List<Organization> organizationsList = myIsernXml.getOrganizations().getOrganization();
    int count = 0;
    for (Organization organization : organizationsList) {
      if (organization.getName().equals(id.replace('_', ' '))) {
        org = organization;
        count = organizationsList.indexOf(org);
      }
    }

    System.out.println();
    System.out.println("Editing organization: " + id.replace('_', ' '));
    System.out.println("To keep values the same just press 'enter'.");
    System.out.println();
    System.out.println("Current type is: " + org.getType());
    System.out.print("Edit organization type: ");
    type = reader.readLine();
    if ("".equals(type)) {
      type = org.getType();
      System.out.println("Type has remained the same.");
    }

    System.out.println();
    System.out.println("Current contact name is: " + org.getContact());
    System.out.print("Edit contact name: ");
    contact = reader.readLine();
    if ("".equals(contact)) {
      contact = org.getContact();
      System.out.println("Contact name has remained the same.");
    }

    System.out.println();
    MyIsernTableCreator creator = new MyIsernTableCreator(myIsernXml);
    String researchersList = creator.createListString(org.getAffiliatedResearchers()
        .getAffiliatedResearcher());
    System.out.println("Current affilated researchers are: " + researchersList);
    System.out.println("To edit affilated researchers, enter 'e'. ");
    System.out.println("To add new affilated researchers, enter 'a'");
    System.out.print(command);
    String choice = reader.readLine();

    while (!("e".equalsIgnoreCase(choice)) && !("a".equalsIgnoreCase(choice))
        && !("".equalsIgnoreCase(choice))) {
      System.out.println(invalidCommand);
      choice = reader.readLine();
    }

    if ("e".equalsIgnoreCase(choice)) {
      System.out.print("Edit affilated researchers (separate by commas): ");
      researcherString = reader.readLine();
      researchers = modifyAffiliatedResearchers(researcherString, researchers);
    }
    else if ("a".equalsIgnoreCase(choice)) {
      System.out.print("Add affilated researchers (separate by commas): ");
      researcherString = reader.readLine();
      researchers = org.getAffiliatedResearchers();
      researchers = modifyAffiliatedResearchers(researcherString, researchers);
    }
    else if ("".equals(choice)) {
      System.out.println("Affiliated Researchers have remained the same.");
    }

    System.out.println();
    System.out.println("Current country is: " + org.getCountry());
    System.out.print("Edit country: ");
    country = reader.readLine();
    if ("".equals(country)) {
      country = org.getCountry();
      System.out.println("Country has remained the same.");
    }

    System.out.println();
    String keywordsList = creator.createListString(org.getAffiliatedResearchers()
        .getAffiliatedResearcher());
    System.out.println("Current research keywords are: " + keywordsList);
    System.out.println("To edit research keywords, enter 'e'.");
    System.out.println("To add new research keywords, enter 'a'.");
    System.out.print(command);
    choice = reader.readLine();

    while (!("e".equalsIgnoreCase(choice)) && !("a".equalsIgnoreCase(choice))
        && !("".equalsIgnoreCase(choice))) {
      System.out.println(invalidCommand);
      choice = reader.readLine();
    }

    if ("e".equalsIgnoreCase(choice)) {
      System.out.print("Edit research keywords (separate by commas): ");
      keywordString = reader.readLine();
      keywords = modifyResearchKeywords(keywordString, keywords);
    }
    else if ("a".equalsIgnoreCase(choice)) {
      System.out.print("Add research keywords (separate by commas): ");
      keywordString = reader.readLine();
      keywords = org.getResearchKeywords();
      keywords = modifyResearchKeywords(keywordString, keywords);
    }
    else if ("".equals(choice)) {
      System.out.println("Research keywords have remained the same.");
      keywords = org.getResearchKeywords();
    }

    System.out.println();
    System.out.println("Current research description is: " + org.getResearchDescription());
    System.out.print("Edit research description: ");
    researchDescription = reader.readLine();
    if ("".equals(researchDescription)) {
      researchDescription = org.getResearchDescription();
      System.out.println("Research description has remained the same.");
    }

    System.out.println();
    System.out.println("Current homepage is: " + org.getHomePage());
    System.out.print("Enter homepage (to delete current homepage, type -delete: )");
    homepage = reader.readLine();

    while ((!(homepage.length() > 5)) && (!(homepage.length() == 0))) {
      System.out.println("Invalid URL or command. Please enter another one: ");
      homepage = reader.readLine();
    }

    while (!(delete.equals(homepage)) && !("".equals(homepage)) && (!(checkLink(homepage)))) {
      if (!(http.equalsIgnoreCase(homepage.substring(0, 6)))) {
        if (www.equalsIgnoreCase(homepage.substring(0, 3))) {
          homepage = http + homepage;
        }
        else {
          homepage = http + www + homepage;
        }
      }
      if (!(checkLink(homepage))) {
        System.out.println(homepageInvalid);
        homepage = reader.readLine();
      }
    }
    if ("".equals(homepage)) {
      homepage = org.getHomePage();
      System.out.println("Homepage has remained the same.");
    }
    else if (delete.equals(homepage)) {
      homepage = "http://www.google.com";
      System.out.println("Original homepage has been deleted.");
    }

    org.setType(type);
    org.setContact(contact);
    org.setAffiliatedResearchers(researchers);
    org.setCountry(country);
    org.setResearchKeywords(keywords);
    org.setResearchDescription(researchDescription);
    org.setHomePage(homepage);

    System.out.println();
    System.out.print("Type 'save' to save this organization or 'cancel' to cancel: ");
    choice = reader.readLine();
    while ((!(save.equals(choice))) && (!(cancel.equals(choice)))) {
      System.out.print(saveOrCancel);
      choice = reader.readLine();
    }
    if (save.equals(choice)) {
      myIsernXml.getOrganizations().getOrganization().set(count, org);
      String newOrganizationsXml = myIsernXml.getOrganizationsXml();
      File organizationsFile = new File(myIsernXml.getOrganizationsFilePath());
      FileOutputStream fos = new FileOutputStream(organizationsFile);
      fos.write(newOrganizationsXml.getBytes());
      System.out.println();
      System.out.println("Organization: " + org.getName() + " has been successfully edited.");
    }
    else {
      System.out.println("Organization: " + org.getName() + " remains the same.");
    }
  }

  /**
   * Checks the given URL to make sure it is a valid link.
   * 
   * @param url The given URL
   * @return If the link is valid or not.  
   */
  public static boolean checkLink(String url) {
    // prevent javascript errors from being thrown
    com.meterware.httpunit.HttpUnitOptions.setExceptionsThrownOnScriptError(false);
    com.meterware.httpunit.HttpUnitOptions.setExceptionsThrownOnErrorStatus(false);
    com.meterware.httpunit.HttpUnitOptions.setScriptingEnabled(false);

    try {
      WebConversation wc = new WebConversation();
      wc.getResponse(url);
    }
    catch (Exception error) {
      return false;
    }
    return true;
  }

  /**
   * Modifies the list of affiliated researchers. 
   * 
   * @param listString The string list of the affiliated researchers.
   * @param affiliates The current list of affiliated researchers.
   * @return The updated list of affiliated researchers. 
   */
  public static AffiliatedResearchers modifyAffiliatedResearchers(String listString,
      AffiliatedResearchers affiliates) {
    String newListString = listString;
    int index = newListString.indexOf(','); 
    String researcher = newListString;
    while (index != -1) {
      researcher = newListString.substring(0, index);
      affiliates.getAffiliatedResearcher().add(researcher.trim());
      newListString = newListString.substring(index + 1);
      index = newListString.indexOf(',');
    }
    researcher = newListString;
    affiliates.getAffiliatedResearcher().add(researcher.trim());

    return affiliates;
  }

  /**
   * Modifies the list of researcher keywords. 
   * 
   * @param listString The string list of the research keywords.
   * @param rKeywords The current list of research keywords.
   * @return The updated list of research keywords.
   */
  public static ResearchKeywords modifyResearchKeywords(String listString,
      ResearchKeywords rKeywords) {
    String newListString = listString;
    int index = newListString.indexOf(',');
    String keyword = newListString;
    while (index != -1) {
      keyword = newListString.substring(0, index);
      rKeywords.getResearchKeyword().add(keyword.trim());
      newListString = newListString.substring(index + 1);
      index = newListString.indexOf(',');
    }
    keyword = newListString;
    rKeywords.getResearchKeyword().add(keyword.trim());

    return rKeywords;
  }

  /**
   * Modifies the list of collaborating organizations.
   * 
   * @param listString The string list of the collaborating organizations.
   * @param organizations The current list of collaborating organizations.
   * @return The updated list of collaborating organizations.
   */
  public static CollaboratingOrganizations modifyCollaboratingOrganizations(String listString,
      CollaboratingOrganizations organizations) {
    String newListString = listString;
    int index = newListString.indexOf(',');
    String organization = newListString;
    while (index != -1) {
      organization = newListString.substring(0, index);
      organizations.getCollaboratingOrganization().add(organization.trim());
      newListString = newListString.substring(index + 1);
      index = newListString.indexOf(',');
    }
    organization = newListString;
    organizations.getCollaboratingOrganization().add(organization.trim());

    return organizations;
  }

  /**
   * Modifies the list of collaboration types.
   * 
   * @param listString The string list of the collaboration types.
   * @param types The current list of collaboration types.
   * @return The updated list of collaboration types.
   */
  public static CollaborationTypes modifyCollaborationTypes(String listString,
      CollaborationTypes types) {
    String newListString = listString;
    int index = newListString.indexOf(',');
    String type = newListString;
    while (index != -1) {
      type = newListString.substring(0, index);
      types.getCollaborationType().add(type.trim());
      newListString = newListString.substring(index + 1);
      index = newListString.indexOf(',');
    }
    type = newListString;
    types.getCollaborationType().add(type.trim());

    return types;
  }

  /**
   * Modifies the list of years.
   * 
   * @param listString The string list of the years of a collaboration.
   * @param yearsList The current list of years.
   * @return The updated list of years.
   * @throws IOException If input problems occur.
   */
  public static Years modifyYears(String listString, Years yearsList) throws IOException {
    if (listString.isEmpty()) {
      return modifyYears("1900", yearsList);
    }
    
    String newListString = listString;
    int index = newListString.indexOf(',');
    String year = newListString;
    BigInteger intYear;
    try {
      while (index != -1) {
        year = newListString.substring(0, index);
        intYear = new BigInteger(year.trim());
        yearsList.getYear().add(intYear);
        newListString = newListString.substring(index + 1);
        index = newListString.indexOf(',');
      }
      year = newListString;
      intYear = new BigInteger(year.trim());
      yearsList.getYear().add(intYear);
    }
    catch (java.lang.NumberFormatException error) {
      System.out.println("Invalid year entered. Please enter again: ");
      String newYears = reader.readLine();
      return modifyYears(newYears, yearsList);
    }

    return yearsList;
  }
  
  /**
   * Modifies the list of outcome types.
   * 
   * @param listString The string list of the outcome types.
   * @param types The current list of outcome types.
   * @return The updated list of outcome types.
   */
  public static OutcomeTypes modifyOutcomeTypes(String listString, OutcomeTypes types) {
    if (listString.isEmpty()) {
      return modifyOutcomeTypes(" ", types);
    }

    String newListString = listString;
    int index = listString.indexOf(',');
    String organization = newListString;
    while (index != -1) {
      organization = newListString.substring(0, index);
      types.getOutcomeType().add(organization.trim());
      newListString = newListString.substring(index + 1);
      index = newListString.indexOf(',');
    }
    organization = newListString;
    types.getOutcomeType().add(organization.trim());

    return types;
  }
}
